local extension = Package:new("plum_blossom")
extension.extensionName = "tuntian_studio"

Fk:loadTranslationTable{
  ["plum_blossom"] = "梅花三弄",
  ["plum"] = "梅花三弄",
}

local U = require "packages/utility/utility"
local TT = require "packages/tuntian_studio/utility"
local R = require "packages/diy_utility/_base"

-- 州泰
local zhoutai = General(extension, "plum__wzhoutai", "wei", 4)
zhoutai.strategy = "courage"
TT.loadGeneral(zhoutai, { name = "州泰", reputation = "解褐拥麾", illustrator = "率土之滨", designer = "妖&淼龙", cv = "始祖鸟", dead = "悬榻在望，寸心难报，唯余死战。" })
local zhoutai_win = fk.CreateActiveSkill{ name = "plum__wzhoutai_win_audio" }
zhoutai_win.package = extension
Fk:addSkill(zhoutai_win)

local exNihiloSkill = fk.CreateActiveSkill{
  name = "xuandai__ex_nihilo_skill",
  mute = true,
  prompt = "#ex_nihilo_skill",
  mod_target_filter = Util.TrueFunc,
  can_use = function(self, player, card)
    return not player:isProhibited(player, card)
  end,
  on_use = function(self, room, cardUseEvent)
    if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
      cardUseEvent.tos = { { cardUseEvent.from } }
    end
  end,
  on_effect = function(self, room, effect)
    local target = room:getPlayerById(effect.to)
    if target.dead then return end
    target:drawCards(2, "ex_nihilo", nil, "@@plum__xuandai-inhand")
  end
}
Fk:loadTranslationTable{
  ["xuandai__ex_nihilo_skill"] = "无中生有",
  ["@@plum__xuandai-inhand"] = "悬待",
}

local xuandai = fk.CreateActiveSkill{
  name = "plum__xuandai",
  anim_type = "drawcard",
  can_use = function (self, player, card, extra_data)
    return player:usedSkillTimes(self.name) < 1
  end,
  card_filter = Util.FalseFunc,
  target_num = 1,
  target_filter = function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected ~= 0 then return end
    return not Fk:currentRoom():getPlayerById(to_select):isNude()
  end,
  on_use = function (self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    -- 无中生有
    local ex_nihilo = Fk:cloneCard("ex_nihilo")
    ex_nihilo.skillName = self.name
    ex_nihilo.skill = exNihiloSkill
    if target:canUseTo(ex_nihilo, player) then
      local sub_card = room:askForCard(target, 1, 1, true, self.name, false, nil, "plum__xuandai-viewas:"..player.id)
      if sub_card then
        ex_nihilo:addSubcards(sub_card)
        room:useCard{
          card = ex_nihilo,
          from = target.id,
          tos = {{player.id}},
        }
      end
    end
    -- 选择
    local choices = {"plum__xuandai_prohibit", "plum__xuandai_discard:"..player.id}
    local xuandai_log = {
      string.format("以此法获得的牌在 %s 下次使用牌前不能被使用", TT.playerToLog(target)),
      string.format("以此法获得的牌在 %s 下次使用牌后需弃置之", TT.playerToLog(player))
    }
    local choice = room:askForChoice(target, choices, self.name, nil, false)
    local arg = xuandai_log[table.indexOf(choices, choice)]
    room:sendLog{type = "#xuandai_choice", from = target.id, arg = arg, toast = true}
    local choice_map = { [choices[1]] = "xd-Ban", [choices[2]] = "xd-Discard" }
    local cards = {}
    for _, id in ipairs(player:getCardIds("h")) do
      local card = Fk:getCardById(id)
      if card:getMark("@@plum__xuandai-inhand") == 1 then
        table.insert(cards, id)
        room:setCardMark(card, "@@plum__xuandai-inhand", 0)
        room:setCardMark(card, "@plum__xuandai-inhand", Fk:translate(choice_map[choice]))
      end
    end
    if choice == choices[1] then -- 在target下次使用牌前不能被使用
      room:setPlayerMark(target, "plum__xuandai-prohibit", {player.id, cards})
      room:handleAddLoseSkills(player, "#plum__xuandai_prohibit")
      room:handleAddLoseSkills(target, "#plum__xuandai_inprohibit")
    else -- 在player下次使用牌后需弃置之
      room:setPlayerMark(player, "plum__xuandai-discard", cards)
      room:handleAddLoseSkills(player, "#plum__xuandai_discard")
    end
  end,
}
TT.loadSkill(xuandai, {
  name = "悬待",
  detail = "出牌阶段限一次，你可以令一名角色将其一张牌当作【无中生有】对你使用，然后其选择一项：1.以此法获得的牌在其下次使用牌前不能被使用；2.以此法获得的牌在你下次使用牌后需弃置之。",
  voices = {"受宣王厚遇，引于行役，委以文武，敢不毕力？", "南北驱驰、载主之忧；九载悬待，当许三生。"}
})

Fk:loadTranslationTable{
  ["plum__xuandai-viewas"] = "悬待：将一张牌当【无中生有】对 %src 使用",
  ["plum__xuandai_prohibit"] = "以此法获得的牌在你下次使用牌前不能被使用",
  ["plum__xuandai_discard"] = "以此法获得的牌在 %src 下次使用牌后需弃置之",
  ["#xuandai_choice"] = "<b>悬待：</b> %from 选择了 <b>%arg</b>",

  ["xd-Ban"] = "<font color='yellow'>禁</font>",
  ["xd-Discard"] = "<font color='yellow'>弃</font>",

  ["@@plum__xuandai-inhand"] = "悬待",
  ["@plum__xuandai-inhand"] = "悬待",
}

local xuandai_prohibit = fk.CreateProhibitSkill{
  name = "#plum__xuandai_prohibit",
  prohibit_use = function(self, player, card)
    return card:getMark("@plum__xuandai-inhand") == Fk:translate("xd-Ban")
  end,
}
TT.loadSkill(xuandai_prohibit, { name = "悬待", })
Fk:addSkill(xuandai_prohibit)

local xuandai_inprohibit = fk.CreateTriggerSkill{
  name = "#plum__xuandai_inprohibit",
  mute = true,
  events = {fk.CardUsing},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) or player ~= target then return false end
    local mark = player:getTableMark("plum__xuandai-prohibit")
    local _zhoutai, cards = mark[1], mark[2]
    return cards and #cards > 0
  end,
  on_trigger = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("plum__xuandai-prohibit")
    local _zhoutai, cards = room:getPlayerById(mark[1]), mark[2]
    local banneds = table.filter(_zhoutai:getCardIds("h"), function (id)
      return Fk:getCardById(id):getMark("@plum__xuandai-inhand") == Fk:translate("xd-Ban")
    end)
    local to_inprohibit = table.filter(banneds, function (id)
      return table.contains(cards, id)
    end)
    for _, id in ipairs(to_inprohibit) do
      local card = Fk:getCardById(id)
      room:setCardMark(card, "@plum__xuandai-inhand", 0)
    end
    room:setPlayerMark(player, "plum__xuandai-prohibit", 0)
    room:handleAddLoseSkills(player, "-"..self.name)
  end,
}
TT.loadSkill(xuandai_inprohibit, { name = "悬待", })
Fk:addSkill(xuandai_inprohibit)

local xuandai_discard = fk.CreateTriggerSkill{
  name = "#plum__xuandai_discard",
  mute = true,
  events = {fk.CardUsing},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) or player ~= target then return false end
    local mark = player:getTableMark("plum__xuandai-discard")
    return #mark > 0
  end,
  on_trigger = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("plum__xuandai-discard")
    local to_discard = table.filter(player:getCardIds("h"), function (id)
      return table.contains(mark, id)
    end)
    if #to_discard > 0 then
      room:throwCard(to_discard, xuandai.name, player, player)
    end
    room:setPlayerMark(player, "plum__xuandai-discard", 0)
    room:handleAddLoseSkills(player, "-"..self.name)
  end,
}
TT.loadSkill(xuandai_discard, { name = "悬待", })
Fk:addSkill(xuandai_discard)

local jubing = fk.CreateTriggerSkill{
  name = "plum__jubing",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    return player.phase == Player.Discard
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local tos = room:getOtherPlayers(player)
    tos = table.map(tos, function (p) return p.id end)
    local to = room:askForChoosePlayers(player, tos, 1, 1, "plum__jubing-choose", self.name, true)
    if #to == 1 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    if to.dead then return end
    local duel = Fk:cloneCard("duel")
    duel.skillName = self.name
    -- 选择
    local all_choices = {"plum__jubing_duel:"..player.id, "plum__jubing_discard:"..player.id}
    local choices = table.simpleClone(all_choices)
    if not to:canUseTo(duel, player) then
      table.removeOne(choices, all_choices[1])
    end
    local op = room:askForChoice(to, choices, self.name, "plum__jubing_choice", false, all_choices)
    -- 清算
    if op == all_choices[1] then
      room:useCard{
        card = duel,
        from = to.id,
        tos = {{player.id}},
      }
    else
      room:setPlayerMark(to, "@@plum__jubing_discard", 1)
      room:handleAddLoseSkills(player, "#plum__jubing_delay")
    end
  end
}
TT.loadSkill(jubing, {
  name = "拒兵",
  detail = "弃牌阶段开始时，你可以令一名其他角色选择一项：视为对你使用一张【决斗】，或于此阶段结束时弃置X张牌（X为你此阶段弃置牌数）。",
  voices = {"车马远路疲弊，旌旗乱乎大泽，吴贼必溃。", "异兵虽众，然劳师远来，号令不从，何谈精强？"}
})

local jubing_delay = fk.CreateTriggerSkill{
  name = "#plum__jubing_delay",
  anim_type = "control",
  events = {fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    return player.phase == Player.Discard
  end,
  on_trigger = function (self, event, target, player, data)
    local room = player.room
    local to = table.find(room.alive_players, function (p) return p:getMark("@@plum__jubing_discard") == 1 end)
    if to then
      local max_num = #to:getCardIds("he")
      local dis_num = 0
      room.logic:getEventsOfScope(GameEvent.MoveCards, max_num, function(e)
        for _, move in ipairs(e.data) do
          if move.proposer == player.id and move.moveReason == fk.ReasonDiscard then
            dis_num = dis_num + #move.moveInfo
            return true
          end
        end
      end, Player.HistoryPhase)
      room:askForDiscard(to, dis_num, dis_num, true, self.name, false)
    end
    room:handleAddLoseSkills(player, "-"..self.name)
  end
}
TT.loadSkill(jubing_delay, { name = "拒兵", })
Fk:addSkill(jubing_delay)

Fk:loadTranslationTable{
  ["plum__jubing-choose"] = "拒兵：选择一名其他角色",
  ["plum__jubing_duel"] = "视为对 %src 使用一张【决斗】",
  ["plum__jubing_discard"] = "于此阶段结束时弃置X张牌（X为 %src 此阶段弃置牌数）",
  ["plum__jubing_choice"] = "拒兵：选择一项",

  ["@@plum__jubing_discard"] = "拒兵",
}

zhoutai:addSkill(xuandai)
zhoutai:addSkill(jubing)

-- 刘琰
local liuyan = General(extension, "plum__liuyans", "shu", 3)
liuyan.strategy = "scheme"
TT.loadGeneral(liuyan, { name = "刘琰", reputation = "玄醴绯颜", illustrator = "谋定天下", designer = "圣园未花", })

local shuyu = fk.CreateViewAsSkill{
  name = "plum_shuyu",
  anim_type = "support",
  pattern = "peach,ex_nihilo",
  interaction = function (self)
    local cardnames = U.getAllCardNames("bt", false)
    local all_choices = table.filter(cardnames, function (name)
      return string.find(name, "peach") or string.find(name, "ex_nihilo")
    end)
    local choices = Self:getTableMark("@$plum_shuyu")
    choices = U.getViewAsCardNames(Self, self.name, choices)
    return U.CardNameBox { choices = choices, all_choices = all_choices, }
  end,
  card_filter = function (self, to_select, selected)
    if #selected == 1 then return end
    return true
  end,
  view_as = function (self, cards)
    if #cards ~= 1 or not self.interaction.data then return end
    local to_use = Fk:cloneCard(self.interaction.data)
    to_use.skillName = self.name
    to_use:addSubcards(cards)
    return to_use
  end,
}
TT.loadSkill(shuyu, { name = "殊遇", detail = "若你最后获得牌的方式不为摸牌，你可将一张牌当【无中生有】使用；"
.."若最后令你回复体力的角色不为自己，你可将一张牌当【桃】使用。", })

local shuyu_trigger = fk.CreateTriggerSkill{
  name = "#plum_shuyu_trigger",
  mute = true,
  events = {fk.AfterCardsMove, fk.HpRecover},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_trigger = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("@$plum_shuyu")
    if event == fk.AfterCardsMove then
      for _, move in ipairs(data) do
        if move.to == player.id and move.toArea == Card.PlayerHand then
          if move.moveReason == fk.ReasonDraw then
            if table.contains(mark, "ex_nihilo") then
              table.removeOne(mark, "ex_nihilo")
            end
          else
            table.insertIfNeed(mark, "ex_nihilo")
          end
        end
      end
    else
      if data.who == player then
        if data.recoverBy == player then
          if table.contains(mark, "peach") then
            table.removeOne(mark, "peach")
          end
        else
          table.insertIfNeed(mark, "peach")
        end
      end
    end
    room:setPlayerMark(player, "@$plum_shuyu", mark)
  end,

  refresh_events = {fk.EventAcquireSkill, fk.EventLoseSkill},
  can_refresh = function (self, event, target, player, data)
    return player == target and data == self
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventAcquireSkill then
      local draw, self_recover = false, false
      room.logic:getEventsByRule(GameEvent.MoveCards, 1, function (e)
        for _, move in ipairs(e.data) do
          if move.to == player.id and move.toArea == Card.PlayerHand then
            draw = (move.moveReason == fk.ReasonDraw) -- 摸牌了吧！
          end
          return true
        end
      end, Player.HistoryGame)
      room.logic:getEventsByRule(GameEvent.Recover, 1, function (e)
        for _, recover in ipairs(data) do
          if recover.who == player then
            self_recover = (recover.recoverBy == player) -- 自奶了吧！
          end
          return true
        end
      end, Player.HistoryGame)
      local mark = {}
      if not draw then table.insert(mark, "ex_nihilo") end
      if not self_recover then table.insert(mark, "peach") end
      player.room:setPlayerMark(player, "@$plum_shuyu", mark)
    else
      player.room:setPlayerMark(player, "@$plum_shuyu", 0)
    end
  end
}
TT.loadSkill(shuyu_trigger, { name = "殊遇", })
shuyu:addRelatedSkill(shuyu_trigger)

Fk:loadTranslationTable{
  ["@$plum_shuyu"] = "殊遇",
}

local jishu = fk.CreateActiveSkill{
  name = "plum_jishu",
  anim_type = "support",
  card_num = 1,
  card_filter = function (self, to_select, selected, selected_targets)
    if #selected == 1 then return end
    return Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand
  end,
  target_num = 1,
  target_filter = function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected == 1 then return end
    return to_select ~= player.id and not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  can_use = function (self, player, card, extra_data)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 1
  end,
  on_use = function (self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local cardM = effect.cards
    local cardsU = target:getCardIds("h")
    if #cardsU == 0 then return false end
    cardsU = room:askForCardsChosen(player, target, 1, 1, "h", self.name, "plum_jishu-exchange")
    U.swapCards(room, player, player, target, cardM, cardsU, self.name)
    if Fk:getCardById(cardM[1]).color == Fk:getCardById(cardsU[1]).color then
      TT.adjustHp(target, player, self.name)
    else
      TT.adjustHp(player, target, self.name)
    end
  end,
}
TT.loadSkill(jishu, { name = "忌束", detail = "出牌阶段限一次，你可与一名其他角色交换一张手牌，"
.."若颜色相同，其将体力向你调整1点，否则你将体力向其调整1点。", })

Fk:loadTranslationTable{
  ["plum_jishu-exchange"] = "忌束：交换一张手牌",
}

liuyan:addSkill(shuyu)
liuyan:addSkill(jishu)

local wanyu = General(extension, "plum__wanyu", "wu", 3)
wanyu.strategy = "scheme"
local banhu = fk.CreateTriggerSkill{
  name = "plum__banhu",
  switch_skill_name = "plum__banhu",
  anim_type = "switch",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    if target and player:hasSkill(self) and not target.dead then
      if player:getSwitchSkillState(self.name, false) == fk.SwitchYang then
        return table.every(player.room.alive_players, function (p)
          return target.hp >= p.hp
        end)
      else
        return table.every(player.room.alive_players, function (p)
          return target:getHandcardNum() >= p:getHandcardNum()
        end)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local prompt = player:getSwitchSkillState(self.name, false, true)
    if player.room:askForSkillInvoke(player, self.name, nil, "#plum__banhu_"..prompt.."-invoke::"..target.id) then
      self.cost_data = {tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player:getSwitchSkillState(self.name, true) == fk.SwitchYang then
      player:drawCards(2, self.name)
      if not target.dead then
        target:drawCards(2, self.name)
      end
    else
      room:loseHp(player, 1, self.name)
      if not target.dead then
        room:loseHp(target, 1, self.name)
      end
    end
  end,
}
local jiliao = fk.CreateActiveSkill{
  name = "plum__jiliao",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#plum__jiliao",
  can_use = function(self, player)
    return not player:isKongcheng() and player:getMark("plum__jiliao-turn") == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, _, _, _, player)
    local target = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and to_select ~= player.id and not target:isKongcheng() and target.faceup
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local discussion = U.Discussion(player, {player, target}, self.name)
    if discussion.color == "red" then
      if not target.dead and not target:isNude() and not player.dead then
        local id = room:askForCardChosen(player, target, "he", self.name, "#plum__jiliao-discard::"..target.id)
        room:throwCard(id, self.name, target, player)
      end
    elseif discussion.color == "black" then
      if not player.dead then
        player:turnOver()
      end
      if not target.dead then
        target:turnOver()
      end
    elseif not player.dead then
      room:addTableMark(player, MarkEnum.InvalidSkills .. "-turn", self.name)
      room:setPlayerMark(player, "plum__jiliao-turn", 1)
      if player:hasSkill(banhu, true) then
        room:setPlayerMark(player, MarkEnum.SwithSkillPreName.."plum__banhu", player:getSwitchSkillState("plum__banhu", true))
        player:addSkillUseHistory("plum__banhu", 1)
      end
    end
  end,
}
wanyu:addSkill(banhu)
wanyu:addSkill(jiliao)
Fk:loadTranslationTable{
  ["plum__wanyu"] = "万彧",
  ["#plum__wanyu"] = "忧拂尊罍",
  ["illustrator:plum__wanyu"] = "鸿图之下",
  ["designer:plum__wanyu"] = "静谦",
  ["cv:plum__wanyu"] = "静谦",
  ["~plum__wanyu"] = "履虎尾者，言其危也……",

  ["plum__banhu"] = "伴虎",
  [":plum__banhu"] = "转换技，当一名角色造成伤害后，若其①体力最大，你可以与其各摸两张牌；②手牌最多，你可以与其各失去1点体力。",
  ["plum__jiliao"] = "讥僚",
  [":plum__jiliao"] = "出牌阶段，你可以与一名武将牌正面向上的其他角色议事，若结果为：红色，你弃置其一张牌；黑色，你与其均翻面；无结果，"..
  "你转换〖伴虎〗且本回合〖讥僚〗失效。",
  ["#plum__banhu_yang-invoke"] = "伴虎：是否与 %dest 各摸两张牌？",
  ["#plum__banhu_yin-invoke"] = "伴虎：是否与 %dest 各失去1点体力？",
  ["#plum__jiliao"] = "讥僚：与一名武将牌正面向上的其他角色议事",
  ["#plum__jiliao-discard"] = "讥僚：弃置 %dest 一张牌",

  ["$plum__banhu1"] = "亦既豹变，刚柔蔚文。",
  ["$plum__banhu2"] = "曷履虎尾，丧其匹羣！",
  ["$plum__jiliao1"] = "此行不急，社稷事重。",
  ["$plum__jiliao2"] = "若至华里，不得不自还。",
}

local wangkuang = General(extension, "plum__wangkuang", "qun", 4)
wangkuang.strategy = "courage"
local qiaoge = fk.CreateTriggerSkill{
  name = "plum__qiaoge",
  anim_type = "control",
  events = {fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and data.card.trueName == "slash" and not target.dead and
      not (data.extra_data and data.extra_data.plum__qiaoge and
        table.contains(data.extra_data.plum__qiaoge, player.id)) then  --防止触发自己
      return table.every(player.room.alive_players, function (p)
        return target:getHandcardNum() >= p:getHandcardNum()
      end) or table.every(player.room.alive_players, function (p)
        return target.hp >= p.hp
      end) or table.every(player.room.alive_players, function (p)
        return #target:getCardIds("e") >= #p:getCardIds("e")
      end)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local success, dat = room:askForUseActiveSkill(player, "plum__qiaoge_active",
      "#plum__qiaoge-invoke::"..data.from..":"..data.card:toLogString(), true, nil, false)
    if success and dat then
      self.cost_data = {tos = dat.targets, cards = dat.cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    data.extra_data = data.extra_data or {}
    data.extra_data.plum__qiaoge = data.extra_data.plum__qiaoge or {}
    table.insert(data.extra_data.plum__qiaoge, player.id)
    if #self.cost_data.tos > 0 then
      room:moveCardTo(self.cost_data.cards, Card.PlayerHand, self.cost_data.tos[1], fk.ReasonGive, self.name, nil, true, player.id)
    else
      room:recastCard(self.cost_data.cards, player, self.name)
    end
    local to = room:getPlayerById(data.from)
    if to.dead then return end
    local targets = table.filter(room:getUseExtraTargets(data, true, true), function (id)
      local q = room:getPlayerById(id)
      return table.every(room.alive_players, function (p)
        return q:getHandcardNum() >= p:getHandcardNum()
      end) or table.every(room.alive_players, function (p)
        return q.hp >= p.hp
      end) or table.every(room.alive_players, function (p)
        return #q:getCardIds("e") >= #p:getCardIds("e")
      end)
    end)
    if #targets == 0 then return end
    local tos = room:askForChoosePlayers(to, targets, 1, 2,
      "#plum__qiaoge-choose::"..data.from..":"..data.card:toLogString(), self.name, true)
    if #tos > 0 then
      for _, id in ipairs(tos) do
        AimGroup:addTargets(room, data, id)
      end
    end
  end,
}

local qiaoge_delay = fk.CreateTriggerSkill{
  name = "#plum__qiaoge_delay",
  anim_type = "drawcard",
  events = {fk.CardEffectCancelledOut},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.extra_data and data.extra_data.plum__qiaoge
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    player:drawCards(1, "plum__qiaoge")
  end,
}

local qiaoge_active = fk.CreateActiveSkill{
  name = "plum__qiaoge_active",
  card_num = 1,
  min_target_num = 0,
  max_target_num = 0,
  card_filter = Util.TrueFunc,
  target_filter = function (self, to_select, selected, selected_cards, _, _, player)
    if #selected_cards == 1 and Fk:getCardById(selected_cards[1]).is_damage_card then
      return #selected == 0 and to_select ~= player.id
    end
  end,
  feasible = function (self, selected, selected_cards)
    if #selected_cards == 1 then
      local card = Fk:getCardById(selected_cards[1])
      if card.is_damage_card then
        return #selected == 1
      else
        return #selected == 0
      end
    end
  end,
}
local liancheng = fk.CreateTriggerSkill{
  name = "plum__liancheng",
  anim_type = "support",
  events = {fk.Deathed},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and table.every(player.room.alive_players, function (p)
      return p.kingdom ~= target.kingdom
    end) and data.damage and data.damage.from and not data.damage.from.dead then
      local to = data.damage.from
      return (to:getHandcardNum() < to:getMaxCards() or to:isWounded() or
        table.find(player.room.discard_pile, function (id)
          local card = Fk:getCardById(id)
          return card.type == Card.TypeEquip and to:hasEmptyEquipSlot(card.sub_type)
        end))
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = data.damage.from
    local choices = {}
    if to:getHandcardNum() < to:getMaxCards() then
      table.insert(choices, "plum__liancheng_draw")
    end
    if to:isWounded() then
      table.insert(choices, "plum__liancheng_recover")
    end
    if table.find(room.discard_pile, function (id)
      local card = Fk:getCardById(id)
      return card.type == Card.TypeEquip and to:hasEmptyEquipSlot(card.sub_type)
    end) then
      table.insert(choices, "plum__liancheng_equip")
    end
    if #choices > 1 then
      table.insert(choices, "plum__liancheng_beishui1")
      if #player:getAvailableEquipSlots() > 0 then
        table.insert(choices, "plum__liancheng_beishui2")
      end
    end
    table.insert(choices, "Cancel")
    local choice = room:askForChoice(player, choices, self.name, "#plum__liancheng-invoke::"..to.id, false,
      {
        "plum__liancheng_draw",
        "plum__liancheng_recover",
        "plum__liancheng_equip",
        "plum__liancheng_beishui1",
        "plum__liancheng_beishui2",
        "Cancel",
      })
    if choice ~= "Cancel" then
      self.cost_data = {tos = {to.id}, choice = choice}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = data.damage.from
    local choice = self.cost_data.choice
    if choice == "plum__liancheng_draw" then
      to:drawCards(to:getMaxCards() - to:getHandcardNum(), self.name)
    elseif choice == "plum__liancheng_recover" then
      room:recover{
        who = to,
        num = to.maxHp - to.hp,
        recoverBy = player,
        skillName = self.name,
      }
    elseif choice == "plum__liancheng_equip" then
      for _, slot in ipairs(to:getAvailableEquipSlots()) do
        if to.dead then return end
        local type = Util.convertSubtypeAndEquipSlot(slot)
        if to:hasEmptyEquipSlot(type) then
          local cards = table.filter(room.discard_pile, function(id)
            local card = Fk:getCardById(id)
            return card.sub_type == type and not to:isProhibited(to, card)
          end)
          if #cards > 0 then
            local card = Fk:getCardById(table.random(cards))
            room:setCardMark(card, MarkEnum.DestructIntoDiscard, 1)
            room:useCard({
              from = to.id,
              tos = {{to.id}},
              card = card,
            })
          end
        end
      end
    else
      if choice == "plum__liancheng_beishui1" then
        room:handleAddLoseSkills(player, "-plum__liancheng", nil, true, false)
      else
        room:abortPlayerArea(player, player:getAvailableEquipSlots())
      end
      if to.dead then return end
      if to:getHandcardNum() < to:getMaxCards() then
        to:drawCards(to:getMaxCards() - to:getHandcardNum(), self.name)
        if to.dead then return end
      end
      if to:isWounded() then
        room:recover{
          who = to,
          num = to.maxHp - to.hp,
          recoverBy = player,
          skillName = self.name,
        }
        if to.dead then return end
      end
      if table.find(room.discard_pile, function (id)
        local card = Fk:getCardById(id)
        return card.type == Card.TypeEquip and to:hasEmptyEquipSlot(card.sub_type)
      end) then
        for _, slot in ipairs(to:getAvailableEquipSlots()) do
          if to.dead then return end
          local type = Util.convertSubtypeAndEquipSlot(slot)
          if to:hasEmptyEquipSlot(type) then
            local cards = table.filter(room.discard_pile, function(id)
              local card = Fk:getCardById(id)
              return card.sub_type == type and not to:isProhibited(to, card)
            end)
            if #cards > 0 then
              local card = Fk:getCardById(table.random(cards))
              room:setCardMark(card, MarkEnum.DestructIntoDiscard, 1)
              room:useCard({
                from = to.id,
                tos = {{to.id}},
                card = card,
              })
            end
          end
        end
      end
    end
  end,
}
qiaoge:addRelatedSkill(qiaoge_delay)
Fk:addSkill(qiaoge_active)
wangkuang:addSkill(qiaoge)
wangkuang:addSkill(liancheng)
Fk:loadTranslationTable{
  ["plum__wangkuang"] = "王匡",
  ["#plum__wangkuang"] = "叱咤喑呜",
  ["illustrator:plum__wangkuang"] = "啪啪三国",
  ["designer:plum__wangkuang"] = "屑",

  ["plum__qiaoge"] = "鞘歌",
  [":plum__qiaoge"] = "手牌数最多、体力值最大或装备区内牌数最多的角色成为【杀】的目标后，你可以交给一名其他角色一张伤害类牌或重铸一张非伤害类牌，"..
  "然后使用者可以令符合上述条件的至多两名角色成为额外目标，若如此做，该【杀】被目标角色抵消时，你摸一张牌。",
  ["plum__liancheng"] = "连城",
  [":plum__liancheng"] = "当一名角色杀死一个势力最后的角色后，你可以令其摸牌、或回复体力、或使用弃牌堆中的装备牌至对应上限。"..
  "背水：失去〖连城〗或废除装备区。",
  ["plum__qiaoge_active"] = "鞘歌",
  ["#plum__qiaoge-invoke"] = "鞘歌：交给一名角色一张伤害类牌或重铸一张非伤害类牌，令 %dest 可以为此%arg增加至多两个目标",
  ["#plum__qiaoge-choose"] = "鞘歌：你可以为此%arg增加至多两个目标",
  ["#plum__qiaoge_delay"] = "鞘歌",
  ["#plum__liancheng-invoke"] = "连城：是否令 %dest 执行一项？",
  ["plum__liancheng_draw"] = "摸牌至手牌上限",
  ["plum__liancheng_recover"] = "回复体力至体力上限",
  ["plum__liancheng_equip"] = "使用弃牌堆中的装备至装备区满",
  ["plum__liancheng_beishui1"] = "背水：你失去〖连城〗",
  ["plum__liancheng_beishui2"] = "背水：你废除所有装备栏",
}

local jingfang = General(extension, "plum__jingfang", "han", 3)
jingfang.strategy = "scheme"
local anjie = fk.CreateTriggerSkill{
  name = "plum__anjie",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local n = #Card:getIdList(data.card)
      return n > 0 and #player:getCardIds("he") >= n and not table.contains(player:getTableMark(self.name), n)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = #Card:getIdList(data.card)
    local cards = room:askForCard(player, n, n, true, self.name, false, nil, "#plum__anjie-recast:::"..n)
    room:recastCard(cards, player, self.name)
    if not player.dead then
      room:addTableMark(player, self.name, n)
    end
  end,

  refresh_events = {fk.AfterCardsMove},
  can_refresh = function(self, event, target, player, data)
    if player:getMark(self.name) == 0 or not player:isNude() then return end
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
            return true
          end
        end
      end
    end
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, self.name, 0)
  end,
}
local jijuan = fk.CreateViewAsSkill{
  name = "plum__jijuan",
  pattern = ".|.|.|.|.|normal_trick",
  prompt = function (self, selected_cards, selected)
    local suits = {}
    for _, id in ipairs(Self:getTableMark("@$plum__jijuan")) do
      table.insertIfNeed(suits, Fk:getCardById(id):getSuitString(true))
    end
    return "#plum__jijuan:::"..table.concat(table.map(suits, Util.TranslateMapper))
  end,
  interaction = function(self)
    local all_names = table.map(Self:getTableMark("@$plum__jijuan"), function (id)
      return Fk:getCardById(id).name
    end)
    local names = U.getViewAsCardNames(Self, self.name, all_names)
    if #names > 0 then
      return U.CardNameBox { choices = names, all_choices = all_names }
    end
  end,
  card_filter = function (self, to_select, selected)
    return not table.find(Self:getTableMark("@$plum__jijuan"), function (id)
      return Fk:getCardById(id):compareSuitWith(Fk:getCardById(to_select))
    end)
  end,
  view_as = function(self, cards)
    if #cards == 0 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    card:addSubcards(cards)
    return card
  end,
  before_use = function (self, player, use)
    local room = player.room
    local mark = player:getTableMark(self.name)
    for i = #mark, 1, -1 do
      if Fk:getCardById(mark[i]).name == use.card.name then
        table.remove(mark, i)
        break
      end
    end
    if #mark == 0 then
      room:setPlayerMark(player, self.name, 0)
      room:setPlayerMark(player, "@$plum__jijuan", 0)
    else
      room:setPlayerMark(player, self.name, mark)
      if #mark < 4 then
        room:setPlayerMark(player, "@$plum__jijuan", mark)
      else
        local mark2 = {}
        for i = #mark, #mark - 2, -1 do
          table.insert(mark2, 1, mark[i])
        end
        room:setPlayerMark(player, "@$plum__jijuan", mark2)
      end
    end
  end,
  enabled_at_play = function(self, player)
    if player:getMark("@$plum__jijuan") == 0 then return end
    for _, id in ipairs(player:getTableMark("@$plum__jijuan")) do
      local card = Fk:cloneCard(Fk:getCardById(id).name)
      card.skillName = self.name
      if player:canUse(card) and not player:prohibitUse(card) then
        return true
      end
    end
  end,
  enabled_at_response = function(self, player, response)
    if response or player:getMark("@$plum__jijuan") == 0 or player:isNude() then return end
    for _, id in ipairs(player:getTableMark("@$plum__jijuan")) do
      local card = Fk:cloneCard(Fk:getCardById(id).name)
      card.skillName = self.name
      if (Fk.currentResponsePattern == nil and player:canUse(card) and not player:prohibitUse(card)) or
        Exppattern:Parse(Fk.currentResponsePattern):match(card) then
        return true
      end
    end
  end,

  on_lose = function (self, player)
    local room = player.room
    room:setPlayerMark(player, "@$plum__jijuan", 0)
    room:setPlayerMark(player, self.name, 0)
  end,
}
local jijuan_trigger = fk.CreateTriggerSkill{
  name = "#plum__jijuan_trigger",

  refresh_events = {fk.AfterCardUseDeclared},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:hasSkill(self, true) and data.card:isCommonTrick() and not data.card:isVirtual()
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:addTableMark(player, "plum__jijuan", data.card.id)
    local mark = player:getTableMark("@$plum__jijuan")
    table.insert(mark, data.card.id)
    if #mark > 3 then
      table.remove(mark, 1)
    end
    room:setPlayerMark(player, "@$plum__jijuan", mark)
  end,
}

local najia = fk.CreateTriggerSkill{
  name = "plum__najia",
  anim_type = "defensive",
  --frequency = Skill.Compulsory,
  events = {fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.trueName == "slash"
    and #AimGroup:getAllTargets(data.tos) == 1 and #player:getEquipments(Card.SubtypeArmor) == 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, data)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local red, black = 0, 0
    for i = 1, 4, 1 do
      room:broadcastPlaySound("./packages/standard_cards/audio/card/eight_diagram")
      room:setEmotion(player, "./packages/standard_cards/image/anim/eight_diagram")
      local judgeData = {
        who = player,
        reason = self.name,
        pattern = ".|.|heart,diamond",
      }
      room:judge(judgeData)
      if judgeData.card.color == Card.Red then
        red = red + 1
      elseif judgeData.card.color == Card.Black then
        player:drawCards(1, self.name)
        black = black + 1
      end
      --if red > black then break end
    end
    local n = black - red
    if n > 0 then
      data.additionalEffect = (data.additionalEffect or 0) + n
    elseif n < 0 then
      table.insertIfNeed(data.nullifiedTargets, player.id)
    end
  end,

}

jijuan:addRelatedSkill(jijuan_trigger)
jingfang:addSkill(anjie)
jingfang:addSkill(jijuan)
jingfang:addSkill(najia)
Fk:loadTranslationTable{
  ["plum__jingfang"] = "京房",
  ["#plum__jingfang"] = "陈商全律",
  ["illustrator:plum__jingfang"] = "率土之滨",
  ["designer:plum__jingfang"] = "屑",
  ["cv:plum__jingfang"] = "易大剧",
  ["~plum__jingfang"] = "人可欺，天不可欺！",

  ["plum__anjie"] = "暗解",
  [":plum__anjie"] = "锁定技，当你使用一张牌后，你重铸转化底牌数张牌，然后不能再以此法重铸此数量张牌，直到你失去所有牌。",
  ["plum__jijuan"] = "集卷",
  [":plum__jijuan"] = "记录你最近三张使用的非转化普通锦囊牌。你可以将任意张花色与被记录牌花色均不同的牌当做一张被记录牌使用，然后视为未使用过此牌。",
  ["plum__najia"] = "纳甲",
  [":plum__najia"] = "当你成为【杀】的唯一目标后，若你未装备防具牌，你可连续进行四次判定，且若结果为：黑色，你摸一张牌，令此【杀】额外生效一次；红色，令此【杀】少生效一次。",
  ["#plum__anjie-recast"] = "暗解：请重铸%arg张牌",
  ["#plum__jijuan"] = "集卷：将任意张牌当一张记录过的锦囊使用（不可使用花色：%arg）",
  ["@$plum__jijuan"] = "集卷",

  ["$plum__anjie1"] = "天垂异，地吐妖，人君之德不明也。",
  ["$plum__anjie2"] = "浊而返清，阴欲为阳，此诸侯欲王也。",
  ["$plum__jijuan1"] = "圣人作《易》，顺性命之理，立三才之道。",
  ["$plum__jijuan2"] = "先天地，本阴阳，观九六之动。",
  ["$plum__najia1"] = "兼三才而两之，易六画而成卦。",
  ["$plum__najia2"] = "分阴阳，用刚柔，易六位而成章。",
}

local lihui = General(extension, "plum__lihui", "shu", 3)
lihui.strategy = "schemecourage"
local plum__liquan = fk.CreateActiveSkill{
  name = "plum__liquan",
  anim_type = "offensive",
  prompt = "#plum__liquan",
  target_num = 1,
  card_num = 0,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, _, _, _, player)
    return player:distanceTo(Fk:currentRoom():getPlayerById(to_select)) == 1
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local choice = room:askForChoice(target, {"plum__liquan1", "plum__liquan2"}, self.name)
    local from = player
    if choice == "plum__liquan1" then from = target end
    room:addPlayerMark(from, "plum__liquan-turn")
    room:notifySkillInvoked(from, "plum__jushou", "drawcard")
    from:turnOver()
    room:drawCards(from, 4, "plum__jushou")
    local jushou_card, throw_card
    for _, id in pairs(from:getCardIds(Player.Hand)) do
      local card = Fk:getCardById(id)
      if (card.type == Card.TypeEquip and not from:prohibitUse(card)) or (card.type ~= Card.TypeEquip and not from:prohibitDiscard(card)) then
        jushou_card = card
        break
      end
    end
    if not jushou_card then return end
    local _, ret = room:askForUseActiveSkill(from, "#plum__jushou_select", "#plum__jushou-select", false)
    if ret then
      jushou_card = Fk:getCardById(ret.cards[1])
    end
    if jushou_card then
      if jushou_card.type == Card.TypeEquip then
        room:useCard({
          from = from.id,
          tos = {{from.id}},
          card = jushou_card,
        })
      else
        throw_card = jushou_card:getEffectiveId()
        room:throwCard(throw_card, self.name, from, from)
      end
    end
    if not throw_card then return end
    if choice == "plum__liquan1" then
      local use = U.askForUseRealCard(room, player, {throw_card}, nil, self.name, "#plum__liquan-use",
      {expand_pile = {throw_card}, bypass_times = true}, true, true)
      room:useCard(use)
    else
      U.askForUseVirtualCard(room, player, "slash", {throw_card}, self.name)
    end
  end,
}

local plum__liquan_trigger = fk.CreateTriggerSkill{
  name = "#plum__liquan_trigger",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      local ids = {}
      player.room.logic:getActualDamageEvents(1, function(e)
        local damage = e.data[1]
        if damage.from == player then
          table.insert(ids, damage.to)
        end
      end)
      return #ids == 2
    end
  end,
  on_use = function(self, event, target, player, data)
    for _, p in ipairs(player.room.alive_players) do
      if p:getMark("plum__liquan-turn") > 0 and not p.faceup then
        p:turnOver()
      end
    end
  end,
}

local plum__xishi = fk.CreateTriggerSkill{
  name = "plum__xishi",
  frequency = Skill.Compulsory,
  events = {fk.TurnedOver},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player.faceup then
      if player:hasSkill("plum__weizhu") then
        room:handleAddLoseSkills(player, "-plum__weizhu")
      end
    else
      room:handleAddLoseSkills(player, "plum__weizhu")
    end
  end,
}

local plum__xishi_distance = fk.CreateDistanceSkill{
  name = "#plum__xishi_distance",
  frequency = Skill.Compulsory,
  correct_func = function(self, from, to)
    if from:hasSkill(self) and from.faceup then
      local n = #table.filter(Fk:currentRoom().alive_players, function (p) return not p.faceup end)
      return -n
    end
  end,
}


local plum__xishi_targetmod = fk.CreateTargetModSkill{
  name = "#plum__xishi_targetmod",
  extra_target_func = function(self, player, skill)
    if player:hasSkill(self) and player.faceup and skill.trueName == "slash_skill" then
      local n = #table.filter(Fk:currentRoom().alive_players, function (p) return not p.faceup end)
      return n
    end
  end,
}

local plum__jushou_select = fk.CreateActiveSkill{
  name = "#plum__jushou_select",
  can_use = Util.FalseFunc,
  target_num = 0,
  card_num = 1,
  card_filter = function(self, to_select, selected)
    if #selected == 0 and Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip then
      local card = Fk:getCardById(to_select)
      if card.type == Card.TypeEquip then
        return not Self:prohibitUse(card)
      else
        return not Self:prohibitDiscard(card)
      end
    end
  end,
}

local plum__jushou = fk.CreateTriggerSkill{
  name = "plum__jushou",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:turnOver()
    if player.dead then return false end
    room:drawCards(player, 4, self.name)
    if player.dead then return false end
    local jushou_card
    for _, id in pairs(player:getCardIds(Player.Hand)) do
      local card = Fk:getCardById(id)
      if (card.type == Card.TypeEquip and not player:prohibitUse(card)) or (card.type ~= Card.TypeEquip and not player:prohibitDiscard(card)) then
        jushou_card = card
        break
      end
    end
    if not jushou_card then return end
    local _, ret = room:askForUseActiveSkill(player, "#plum__jushou_select", "#plum__jushou-select", false)
    if ret then
      jushou_card = Fk:getCardById(ret.cards[1])
    end
    if jushou_card then
      if jushou_card.type == Card.TypeEquip then
        room:useCard({
          from = player.id,
          tos = {{player.id}},
          card = jushou_card,
        })
      else
        room:throwCard(jushou_card:getEffectiveId(), self.name, player, player)
        room:setBanner("plum__jushou_throw", jushou_card:getEffectiveId())
      end
    end
  end,
}

local plum__weizhu = fk.CreateTriggerSkill{
  name = "plum__weizhu",
  anim_type = "offensive",
  events = {fk.TargetSpecified, fk.TargetConfirmed, fk.CardEffectCancelledOut},
  can_trigger = function(self, event, target, player, data)
    if data.card.trueName ~= "slash" or not player:hasSkill(self) then return false end
    if event == fk.TargetSpecified then
      return target == player
    elseif event == fk.TargetConfirmed then
      return data.to == player.id
    else
      return (data.from == player.id or data.to == player.id) and data.extra_data and data.extra_data.weizhu
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      return player.room:askForSkillInvoke(player, self.name)
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.TargetSpecified or event == fk.TargetConfirmed then
      data.fixedResponseTimes = data.fixedResponseTimes or {}
      data.fixedResponseTimes["jink"] = 2
      data.extra_data = data.extra_data or {}
      data.extra_data.weizhu = true
    else
      player.room:getPlayerById(data.from):turnOver()
    end
  end,
}

plum__jushou:addRelatedSkill(plum__jushou_select)
plum__liquan:addRelatedSkill(plum__liquan_trigger)
plum__xishi:addRelatedSkill(plum__xishi_distance)
plum__xishi:addRelatedSkill(plum__xishi_targetmod)
Fk:addSkill(plum__jushou)
Fk:addSkill(plum__weizhu)
lihui:addSkill(plum__liquan)
lihui:addSkill(plum__xishi)
lihui:addRelatedSkill("plum__jushou")
lihui:addRelatedSkill("plum__weizhu")

Fk:loadTranslationTable{
  ["plum__lihui"] = "李恢",
  ["#plum__lihui"] = "叙业成肱",
  ["illustrator:plum__lihui"] = "啪啪三国",
  ["designer:plum__lihui"] = "拉普拉斯",
  ["plum__liquan"] = "力劝",
  [":plum__liquan"] = "出牌阶段限一次，你可令一名距离为1的角色选择一项：1.其发动“据守”并令你使用因此弃置的牌；2.你发动“据守”并将因此弃置的牌当【杀】使用。本回合你累计对两名角色造成伤害后，令因此发动“据守”的角色翻至正面。",
  ["#plum__liquan"] = "力劝：你可以选择一名其他角色",
  ["plum__liquan1"] = "你发动“据守”并令李恢使用因此弃置的牌",
  ["plum__liquan2"] = "李恢发动“据守”并将因此弃置的牌当【杀】使用",
  ["#plum__liquan-use"] = "力劝：请使用因此弃置的牌",
  ["plum__xishi"] = "析势",
  [":plum__xishi"] = "若你正面朝上，你至其他角色距离-X且使用【杀】目标上限+X（X为背面向上角色数）；若你背面向上，你拥有“威驻”。",
  ["plum__jushou"] = "据守",
  [":plum__jushou"] = "结束阶段，你可摸四张牌并翻面，然后弃置一张手牌（若此牌为装备牌，改为使用之）。",
  ["#plum__jushou_select"] = "据守",
  ["#plum__jushou-select"] = "据守：选择使用手牌中的一张装备牌或弃置手牌中的一张非装备牌",
  ["plum__weizhu"] = "威驻",
  [":plum__weizhu"] = "你使用【杀】或成为【杀】的目标时，可将之的抵消方式改为连续使用两张【闪】，若如此做，此【杀】被抵消后，使用者须翻面。",
}

local qindan = General(extension, "plum__qindan", "wu", 3)
TT.loadGeneral(qindan, { name = "秦旦", reputation = "燎亡北流", illustrator = "xiaomartin", designer = "yyuaN", cv = "胖即是胖", dead = "吾不幸创甚，死亡无日……" })

--- 多少偶数？
---@param player ServerPlayer
---@return number
local weihuanEven = function (player)
  local count = 0
  local hp, hand, distribution = player.hp, #player:getCardIds(Card.PlayerHand), 0

  local logic = player.room.logic
  local use_events = logic:getEventsOfScope(GameEvent.UseCard, 999, function (e) return true end, Player.HistoryTurn)
  for _, e in ipairs(use_events) do
    if e.data[1].from == player.id then
      distribution = distribution + 1
    end
  end

  for _, num in ipairs {hp, hand, distribution} do
    if num % 2 == 0 then
      count = count + 1
    end
  end
  return count
end

local weihuan = fk.CreateTriggerSkill {
  name = "plum__weihuan",
  anim_type = "drawcard",
  events = {fk.TurnEnd, fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.TurnEnd then
      return weihuanEven(player) % 2 == 0
    elseif event == fk.EventPhaseEnd then
      return player == target and player.phase == Player.Finish
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.TurnEnd then
      return true
    elseif event == fk.EventPhaseEnd then
      local num = weihuanEven(player)
      local tos = table.map(table.filter(room.alive_players, function (p)
        return p:getHandcardNum() <= player:getHandcardNum() end), Util.IdMapper)
      local to = room:askForChoosePlayers(player, tos, 1, 1, "weihuan-choose:::"..num, self.name, true)
      if #to == 1 then
        self.cost_data = { to = to[1], num = num }
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.TurnEnd then
      player:drawCards(1, self.name)
    elseif event == fk.EventPhaseEnd then
      local to = room:getPlayerById(self.cost_data.to)
      local num = self.cost_data.num
      TT.adjustHandNum(to, num, self.name)
    end
  end,
}
TT.loadSkill(weihuan, {
  name = "为宦",
  detail = "结束阶段，你可以令一名手牌数不大于你的角色将手牌数调整至Ｘ（Ｘ为你为偶数的项数：体力值、手牌数、本回合使用牌数）。每回合结束时，若Ｘ为偶数，你摸一张牌。",
  voices = {"卿诸人宜速进道，冀有所达。", "吾人远辱国命，自弃於此，与死亡何异？", }
})

local liucang = fk.CreateTriggerSkill {
  name = "plum__liucang",
  anim_type = "defensive",
  events = {fk.DamageInflicted },
  can_trigger = function (self, event, target, player, data)
    local room = player.room
    if not player:hasSkill(self) then return end
    if event == fk.DamageInflicted and not player:isNude() then
      return target == player
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.DamageInflicted then
      local tos = table.map(room:getOtherPlayers(player), Util.IdMapper)
      local to, cards, op = room:askForChooseCardsAndPlayers(player, 1, 999, tos, 1, 1, nil, "liucang-choose", self.name)
      if op then
        self.cost_data = { to = to[1], cards = cards }
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.DamageInflicted then
      local to = room:getPlayerById(self.cost_data.to)
      local cards = self.cost_data.cards
      room:showCards(cards, player)
      cards = table.filter(cards, function (id) return room:getCardOwner(id) == player end)
      if to.dead then return end
      room:obtainCard(to, cards, true, fk.ReasonGive, player.id, self.name, "@@plum__liucang")
      room.logic:getCurrentEvent():findParent(GameEvent.Damage, true, Player.HistoryGame):addCleaner(function ()
        for _, cardId in ipairs(cards) do
          room:setCardMark(Fk:getCardById(cardId), "@@plum__liucang", 0)
        end
      end)
      if to.dead then return end
      room:damage{
        from = data.from,
        to = to,
        damage = data.damage,
        damageType = fk.IceDamage,
        skillName = data.skillName,
        chain = data.chain,
        card = data.card,
      }
      if player.dead then return end
      local this = room.logic:getCurrentEvent()
      for i = this.id, #room.logic.all_game_events do
        local e = room.logic.all_game_events[i]
        if e.event == GameEvent.MoveCards then
          for _, move in ipairs(e.data) do
            if move.from == to.id and move.skillName == "#tuntian_iceDamage" then
              for _, info in ipairs(move.moveInfo) do
                if table.contains(cards, info.cardId) then
                  table.removeOne(cards, info.cardId)
                  if #cards == 0 then
                    room:loseHp(player, 1, self.name)
                    break
                  end
                end
              end
            end
          end
        end
      end
      return true
    end
  end,
}
TT.loadSkill(liucang, {
  name = "流藏",
  detail = "你受到伤害时，可以展示并交给一名其他角色任意张牌，令此伤害改为冰属性并转移给其。若交出牌均因此被弃置，你失去1点体力。",
  voices = {"为国报耻，然后伏死，足以无恨。", "万里流离，死生共之。", }
})

qindan:addSkill(weihuan)
qindan:addSkill(liucang)

Fk:loadTranslationTable{
  ["weihuan-choose"] = "为宦：可以令一名角色将手牌数调整至%arg",

  ["liucang-choose"] = "流藏：可以可以展示并交给一名其他角色任意张牌，令此伤害改为冰属性并转移给其",
  ["@@plum__liucang"] = "流藏",
}

local lifu = General(extension, "plum__lifu", "wei", 4)
lifu.subkingdom = "qun"
lifu.strategy = "scheme"
TT.loadGeneral(lifu, { name = "李孚", reputation = "委身幅重", illustrator = "率土之滨", designer = "Mushi", })

local xiwei = fk.CreateActiveSkill {
  name = "plum__xiwei",
  anim_type = "special",
  can_use = function (self, player, card, extra_data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function (self, to_select, selected, selected_targets)
    return false
  end,
  target_num = 1,
  target_filter = function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected > 0 then return false end
    return to_select ~= player.id
  end,
  on_use = function (self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    if target:getHandcardNum() > 0 then
      local to_top = room:askForCard(target, 1, 2, true, self.name, false, nil, "xiwei-put:"..player.id)
      room:moveCardTo(to_top, Card.DrawPile, nil, fk.ReasonPut, self.name)
    end

    local card = Fk:cloneCard("tuntian__enemy_at_the_gates")
    card.skillName = self.name
    if player.dead or target.dead or target:isProhibited(player, card) then return end
    room:useCard {
      card = card,
      from = target.id,
      tos = { {player.id} },
      skillName = self.name,
    }
  end,
}
local xiwei_use = fk.CreateTriggerSkill {
  name = "#plum__xiwei_use",
  mute = true,
  events = {TT.ReviewToDiscardPile},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(xiwei) then return end
    return #data.cards > 0
  end,
  on_trigger = function (self, event, target, player, data)
    self.cancel_cost = false
    for _ = 1, #data.cards do
      if self.cancel_cost or not player:hasSkill(self) then break end
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local all_cards = table.filter(data.cards, function (id) return room:getCardArea(id) == Card.Processing end)
    local jinks = table.filter(all_cards, function (id) return Fk:getCardById(id).trueName == "jink" end)
    local able_cards = table.filter(all_cards, function (id) return player:canUse(Fk:getCardById(id), {bypass_times = true}) end)
    room:moveCardTo(jinks, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
    local _, ret = room:askForUseActiveSkill(player, "realcard_viewas", "xiwei-use", true, { optional_cards = able_cards, expand_pile = all_cards, bypass_times = true })
    if ret then
      local use = {
        card = Fk:getCardById(ret.cards[1]),
        from = player.id,
        tos = table.map(ret.targets, function(p) return {p} end),
        extraUse = true,
      }
      self.cost_data = use
      return true
    else
      self.cancel_cost = true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:useCard(self.cost_data)
  end,
}
xiwei:addRelatedSkill(xiwei_use)

TT.loadSkill(xiwei, {
  name = "隙围",
  detail = "出牌阶段限一次，你可以令一名其他角色将至多两张牌置于牌堆顶并视为对你使用一张【兵临城下】，然后你可使用剩余亮出牌并获得亮出的【闪】。",
})

Fk:loadTranslationTable{
  ["xiwei-put"] = "隙围：将至多两张牌置于牌堆顶",
  ["xiwei-use"] = "隙围：可以使用以此法亮出的其余牌",
}

local canxu_left = fk.CreateViewAsSkill {
  name = "plum__canxu_left&",
  anim_type = "special",
  pattern = "slash,jink,tuntian__shade",
  interaction = function (self)
    local all_choices = {"slash", "jink", "tuntian__shade"}
    local choices = U.getViewAsCardNames(Self, self.name, all_choices, nil, Self:getTableMark(self.name))
    return U.CardNameBox { choices = choices, all_choices = all_choices, }
  end,
  card_num = 1,
  card_filter = function (self, to_select, selected)
    if #selected > 0 then return false end
    return table.contains({"slash", "jink"}, Fk:getCardById(to_select).trueName) and table.contains(Self:getCardIds("h"), to_select)
  end,
  view_as = function (self, cards)
    if #cards ~= 1 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    card:addSubcards(cards)
    return card
  end,
}
local canxu_left_prohibit = fk.CreateProhibitSkill {
  name = "#plum__canxu_left_prohibit",
  prohibit_use = function(self, player, card)
    return player:hasSkill(canxu_left) and table.contains({"slash", "jink"}, card.trueName) and table.contains(player:getCardIds("h"), card.id)
  end,
  prohibit_response = function(self, player, card)
    return player:hasSkill(canxu_left) and table.contains({"slash", "jink"}, card.trueName) and table.contains(player:getCardIds("h"), card.id)
  end,
}
canxu_left:addRelatedSkill(canxu_left_prohibit)
TT.loadSkill(canxu_left, { name = "掺虚", detail = "你可以将手牌的一张【杀】或【闪】当【杀】或【闪】或【影】使用。" })
Fk:addSkill(canxu_left)

local canxu_right = fk.CreateViewAsSkill {
  name = "plum__canxu_right&",
  anim_type = "special",
  pattern = "peach,analeptic,tuntian__shade",
  interaction = function (self)
    local all_choices = {"peach", "analeptic", "tuntian__shade"}
    local choices = U.getViewAsCardNames(Self, self.name, all_choices, nil, Self:getTableMark(self.name))
    return U.CardNameBox { choices = choices, all_choices = all_choices, }
  end,
  card_num = 1,
  card_filter = function (self, to_select, selected)
    if #selected > 0 then return false end
    return table.contains({"peach", "analeptic"}, Fk:getCardById(to_select).trueName) and table.contains(Self:getCardIds("h"), to_select)
  end,
  view_as = function (self, cards)
    if #cards ~= 1 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    card:addSubcards(cards)
    return card
  end,
}
local canxu_right_prohibit = fk.CreateProhibitSkill {
  name = "#plum__canxu_right_prohibit",
  prohibit_use = function(self, player, card)
    return player:hasSkill(canxu_right) and table.contains({"peach", "analeptic"}, card.trueName) and table.contains(player:getCardIds("h"), card.id)
  end,
  prohibit_response = function(self, player, card)
    return player:hasSkill(canxu_right) and table.contains({"peach", "analeptic"}, card.trueName) and table.contains(player:getCardIds("h"), card.id)
  end,
}
canxu_right:addRelatedSkill(canxu_right_prohibit)
TT.loadSkill(canxu_right, { name = "掺虚", detail = "你可以将手牌的一张【桃】或【酒】当【桃】或【酒】或【影】使用。" })
Fk:addSkill(canxu_right)

local canxu = fk.CreateTriggerSkill {
  name = "plum__canxu",
  anim_type = "special",
  events = {fk.TurnStart},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return end
    return player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 2, 2, "canxu-choose", self.name, true)
    if #tos == 2 then
      self.cost_data = { tos = tos }
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local tos = self.cost_data.tos
    local left_one = room:getPlayerById(tos[1])
    room:setPlayerMark(left_one, canxu_left.name, {})
    room:handleAddLoseSkills(left_one, canxu_left.name)
    local right_one = room:getPlayerById(tos[2])
    room:setPlayerMark(right_one, canxu_right.name, {})
    room:handleAddLoseSkills(right_one, canxu_right.name)
    room.logic:getCurrentEvent():findParent(GameEvent.Turn, true, Player.HistoryGame):addCleaner(function ()
      room:setPlayerMark(left_one, canxu_left.name, 0)
      room:handleAddLoseSkills(left_one, "-"..canxu_left.name)
      room:setPlayerMark(right_one, canxu_right.name, 0)
      room:handleAddLoseSkills(right_one, "-"..canxu_right.name)
    end)
  end,
}
local canxu_refresh = fk.CreateTriggerSkill {
  name = "#plum__canxu_refresh",

  refresh_events = {fk.CardUsing},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(canxu.name) and data.card.type == Card.TypeBasic
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room.alive_players) do
      if p:hasSkill(canxu_left) then
        local mark = p:getTableMark(canxu_left.name)
        table.insertIfNeed(mark, data.card.trueName)
        room:setPlayerMark(p, canxu_left.name, mark)
      end
      if p:hasSkill(canxu_right) then
        local mark = p:getTableMark(canxu_right.name)
        table.insertIfNeed(mark, data.card.trueName)
        room:setPlayerMark(p, canxu_right.name, mark)
      end
    end
  end,
}
canxu:addRelatedSkill(canxu_refresh)
TT.loadSkill(canxu, {
  name = "掺虚",
  detail = "每轮限一次，一名角色的回合开始时，你可以指定两名角色，前者的【杀】本回合内视为【杀/闪/影】，后者的【桃】和【酒】于本回合内视为【桃/酒/影】，有角色使用基本牌时，本回合移去“/”左侧的相同牌名。",
})
Fk:loadTranslationTable {
  ["#plum__canxu_left_prohibit"] = "掺虚",
  ["#plum__canxu_right_prohibit"] = "掺虚",
  ["canxu-choose"] = "参虚：可以选择两名角色，本回合，前者的【杀】和【闪】视为【杀/闪/影】， 后者的【桃】和【酒】视为【桃/酒/影】",
}

lifu:addSkill(xiwei)
lifu:addSkill(canxu)

local huanyi = General(extension, "plum__huanyi", "jin", 3)
TT.loadGeneral(huanyi, {name = "桓伊", reputation = "梅花三弄", illustrator = "久吉-FG", designer = "食马者", })

Fk:addQmlMark{
  name = "nongdi_cards",
  qml_path = function(name, value, p)
    if Self == p then
      return "packages/tuntian_studio/qml/CardsOrder"
    end
    return ""
  end,
  how_to_show = function(name, value, p)
    return " "
  end,
}

local nongdi = fk.CreateActiveSkill {
  name = "plum__nongdi",
  anim_type = "special",
  interaction = function (self, player)
    local n = player:getMark("@plum__nongdi")
    local all_choices = {"nongdi_discard", "nongdi_reveal:::"..n}
    local choices = table.simpleClone(all_choices)
    if player:getHandcardNum() < n then
      table.remove(choices, 2)
    end
    return UI.ComboBox { choices = choices, all_choices = all_choices, }
  end,
  card_num = 1,
  card_filter = function (self, to_select, selected, player)
    if self.interaction.data == "nongdi_discard" then
      return #selected == 0 and not player:prohibitDiscard(to_select)
    else
      return to_select == player:getCardIds("h")[player:getMark("@plum__nongdi")]
      and not table.contains(R.GetShownCards(player), to_select)
    end
  end,
  target_filter = Util.FalseFunc,
  on_use = function (self, room, effect)
    local player = room:getPlayerById(effect.from)
    local cardId = effect.cards[1]
    local combo = player:getTableMark("nongdi_combo")
    if self.interaction.data == "nongdi_discard" then
      table.insert(combo, 1)
      room:setPlayerMark(player, "nongdi_combo", combo)
      room:throwCard(cardId, self.name, player, player)
    else
      table.insert(combo, 2)
      room:setPlayerMark(player, "nongdi_combo", combo)
      R.ShowCards(player, cardId)
    end
    if player.dead then return end
    local card = Fk:getCardById(cardId)
    local num
    if card.suit and card.suit == Card.Club then
      local choices = {}
      for i = 1, 99 do
        table.insert(choices, tostring(i))
      end
      num = room:askForChoice(player, choices, self.name, "#nongdi_choose")
    elseif card.number and card.number > 0 then
      num = card.number
    end
    if num then
      room:setPlayerMark(player, "@plum__nongdi", tonumber(num))
    end
  end,

  on_acquire = function (self, player, is_start)
    local room = player.room
    room:setPlayerMark(player, "@plum__nongdi", 1)
    room:setPlayerMark(player, "@[nongdi_cards]", { value = player.id })
  end,
  on_lose = function (self, player, is_death)
    local room = player.room
    room:setPlayerMark(player, "@plum__nongdi", 0)
    room:setPlayerMark(player, "@[nongdi_cards]", 0)
  end,
}
local nongdi_refresh = fk.CreateTriggerSkill {
  name = "#plum__nongdi_refresh",

  refresh_events = {fk.AfterCardsMove, fk.EventPhaseStart, fk.EventPhaseEnd},
  can_refresh = function(self, event, target, player, data)
    if not player:hasSkill(nongdi) then return end
    if event == fk.AfterCardsMove then
      return table.find( data, function(move)
        return (move.to == player.id and move.toArea == Card.PlayerHand)
        or (move.from == player.id and table.find(move.moveInfo, function(info)
          return info.fromArea == Card.PlayerHand
        end))
      end)
    else
      return player.phase == Player.Play
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardsMove then
      if player:getMark("@[nongdi_cards]") == 0 then
        room:setPlayerMark(player, "@[nongdi_cards]", { value = player.id })
      end
    elseif event == fk.EventPhaseStart then
      room:setPlayerMark(player, MarkEnum.SortProhibited, 1)
    else
      room:setPlayerMark(player, MarkEnum.SortProhibited, 0)
    end
  end,
}
nongdi:addRelatedSkill(nongdi_refresh)

TT.loadSkill(nongdi, { name = "弄笛",
  detail = "你不能整理手牌；出牌阶段你可以：①弃置一张牌；②明置左侧第（1）张手牌；然后（）中数字改为之点数。若该牌为♣牌，（）内数字由你指定。",
})
Fk:loadTranslationTable {
  ["@[nongdi_cards]"] = "弄笛[牌序]",
  ["@plum__nongdi"] = "弄笛",
  ["nongdi_discard"] = "弃置一张牌",
  ["nongdi_reveal"] = "明置左侧第%arg张手牌",
}

huanyi:addSkill(nongdi)

local puyun = fk.CreateTriggerSkill {
  name = "plum__puyun",
  anim_type = "support",
  events = {fk.AfterSkillEffect},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) or data.name ~= "plum__nongdi" then return end
    local condition = player:getTableMark("plum__puyun")
    local times = 0
    local combo = player:getTableMark("nongdi_combo")
    if #combo < 3 then return end
    for _, c in ipairs(combo) do
      if c >= condition[times+1] then
        times = times + 1
      end
      if times == 3 then
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local condition = player:getTableMark("plum__puyun")
    local combo = player:getTableMark("nongdi_combo")
    room:setPlayerMark(player, "nongdi_combo", {})
    if #table.filter(combo, function (c) return c == 2 end) >= 3 then
      local targets = room.alive_players
      local tos = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 3, "puyun_choose_targets", self.name, true)
      if #tos == 0 then return end
      room:sortPlayersByAction(tos)
      local choose = room:askForChoice(player, {"lose_hp", "heal_hp"}, self.name, "puyun_choose_effect")
      for _, p in ipairs(tos) do
        if not room:getPlayerById(p).dead then
          if choose == "lose_hp" then
            room:loseHp(room:getPlayerById(p), 1)
          else
            room:recover{ who = room:getPlayerById(p), num = 1, skillName = self.name, recoverBy = player, }
          end
        end
      end
    else
      player:drawCards(2, self.name)
      if player.dead or not table.contains(condition, 1) then return end
      local choices = {}
      for i = 1, 3 do
        if condition[i] == 1 then
          table.insert(choices, tostring(i))
        end
      end
      local num = room:askForChoice(player, choices, self.name, "puyun_choose_condition")
      condition[tonumber(num)] = 2
      room:setPlayerMark(player, "plum__puyun", condition)
      local babyMark = table.map(condition, function (c)
        if c == 1 then
          return "弄"
        else
          return "弄②"
        end
      end)
      babyMark = table.concat(babyMark, "+")
      player.room:setPlayerMark(player, "@plum__puyun", babyMark)
    end
  end,

  refresh_events = {fk.TurnEnd},
  can_refresh = Util.TrueFunc,
  on_refresh = function (self, event, target, player, data)
    if not player:hasSkill(self) then return end
    player.room:setPlayerMark(player, "plum__puyun", {1, 1, 1})
    player.room:setPlayerMark(player, "@plum__puyun", "弄+弄+弄")
  end,

  on_acquire = function (self, player, is_start)
    player.room:setPlayerMark(player, "plum__puyun", {1, 1, 1})
    player.room:setPlayerMark(player, "@plum__puyun", "弄+弄+弄")
  end,
  on_lose = function (self, player, is_death)
    player.room:setPlayerMark(player, "plum__puyun", 0)
    player.room:setPlayerMark(player, "@plum__puyun", 0)
  end,
}

TT.loadSkill(puyun, { name = "谱韵",
  detail = "连招技（“弄笛”+“弄笛”+“弄笛”），若全因“弄笛②”达成，你对至多三名角色发动“琴音”，否则你摸两张牌并将一个连招条件改为“弄笛②”直到回合结束。",
})
Fk:loadTranslationTable {
  ["puyun_choose_targets"] = "谱韵：请选择至多3名目标，对其发动“琴音”",
  ["puyun_choose_effect"] = "谱韵：请选择“琴音”效果",
  ["puyun_choose_condition"] = "谱韵：请选择要修改的连招条件（第几个？）",

  ["@plum__puyun"] = "",
}

huanyi:addSkill(puyun)

local yuwanghou = General(extension, "plum__yuwanghou", "qun", 3, 3, General.Female)
TT.loadGeneral(yuwanghou, {name = "于王后", reputation = "月懸高麗", illustrator = "啪啪三国", designer = "白驹", })

local midang = fk.CreateTriggerSkill {
  name = "plum__midang",
  anim_type = "support",
  events = {fk.CardEffectFinished},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) then
      return data.to and data.to == player.id and data.card.extra_data and data.card.extra_data.midang_quit and (data.card.type == Card.TypeBasic or data.card:isCommonTrick())
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local targets = room.alive_players
    local tos = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "midang_choose_target", self.name, true)
    if #tos ~= 1 then return end
    self.cost_data = tos[1]
    return true
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    if not to or to.dead then return end
    room:setPlayerMark(to, "@@plum__midang", 1)
    to.tag["midang_boss"] = player.id
  end,

  refresh_events = {fk.AfterAskForNullification, fk.AfterAskForCardUse},
  can_refresh = function (self, event, target, player, data)
    if player:hasSkill(self) and (target == player or event == fk.AfterAskForNullification) then
      return data.eventData and data.eventData.to and data.eventData.to == player.id
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local extra_data = data.eventData.card.extra_data or {}
    extra_data.midang_quit = not data.result
    data.eventData.card.extra_data = extra_data
  end,

  on_acquire = function (self, player, is_start)
    local room = player.room
    for _, p in ipairs(room.players) do
      room:handleAddLoseSkills(p, "#plum__midang_response")
    end
  end,
}

local midang_draw = fk.CreateTriggerSkill {
  name = "#plum__midang_draw",
  anim_type = "support",
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, data, "#midang_draw")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    data.n = 1
    room.logic:getCurrentEvent():findParent(GameEvent.Phase, true, Player.HistoryGame):addExitFunc(function ()
      local tos = table.filter(room.alive_players, function (p) return p:getMark("@@plum__midang") == 1 end)
      for _, p in ipairs(tos) do
        if not p.dead then
          room:drawCards(p, 1, self.name)
        end
      end
    end)
  end,
}
midang:addRelatedSkill(midang_draw)

local midang_response = fk.CreateTriggerSkill {
  name = "#plum__midang_response",
  anim_type = "defensive",
  events = {fk.PreCardEffect},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and data.to == player.id and player:getMark("@@plum__midang") == 1 then
      return (data.card.type == Card.TypeBasic or data.card:isCommonTrick())
      and not (data.unoffsetable or data.disresponsive or table.contains(data.unoffsetableList or {}, player.id) or table.contains(data.disresponsiveList or {}, player.id))
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "@@plum__midang", 0)
    return true
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local boss = player.tag["midang_boss"]
    if boss and room:askForSkillInvoke(player, self.name, data, "#midang_response:"..boss.."::"..data.card:toLogString()) then
      room:getPlayerById(boss):drawCards(1, midang.name)
      return true
    else
      data.unoffsetableList = data.unoffsetableList or {}
      table.insert(data.unoffsetableList, player.id)
    end
  end,
}
Fk:addSkill(midang_response)

TT.loadSkill(midang, { name = "密党",
  detail = "你未抵消对你生效的即时牌后，你可以选择一名角色，下张即时牌对其生效前，抵消方式改为令你摸一张牌。摸牌阶段，你可以改为与这些角色各摸一张牌。",
})

Fk:loadTranslationTable {
  ["midang_choose_target"] = "密党：可以选择一名角色，下张即时牌对其生效前，抵消方式改为令你摸一张牌",
  ["@@plum__midang"] = "密党",

  ["#plum__midang_draw"] = "密党",
  ["#midang_draw"] = "你是否想要发动“密党”改为与密党角色各摸一张牌？",
  ["#plum__midang_response"] = "密党",
  ["#midang_response"] = "你是否想要发动“密党”令%src摸一张牌来抵消%arg？",
}

yuwanghou:addSkill(midang)

local tunquan = fk.CreateTriggerSkill {
  name = "plum__tunquan",
  anim_type = "offensive",
  events = {fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Finish and not player:isNude()
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local cards = room:askForDiscard(player, 1, 999, true, self.name, true, nil, "#tunquan_discard", true)
    if #cards == 0 then return end
    self.cost_data = cards
    return true
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local cards = self.cost_data
    room:throwCard(cards, self.name, player, player)
    if player.dead then return end
    local card = Fk:cloneCard("archery_attack")
    card.skillName = self.name
    local targets = table.filter(room.alive_players, function (p) return p ~= player and p:getHandcardNum() >= player:getHandcardNum() and not player:isProhibited(p, card) end)
    if #targets == 0 then return end
    if #table.filter(player.room.alive_players, function (p) return p ~= player and p:getHandcardNum() < player:getHandcardNum() end) == 0 then
      room:handleAddLoseSkills(player, "#plum__tunquan_levelup")
    end
    room:useCard{
      card = card,
      tos = table.map(targets, function (p) return {p.id} end),
      from = player.id,
      skillName = self.name,
    }
  end,
}

local tunquan_levelup = fk.CreateTriggerSkill {
  name = "#plum__tunquan_levelup",
  anim_type = "support",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      return #table.filter(player.room.alive_players, function (p) return p ~= player and p:getHandcardNum() > player:getHandcardNum() end) == 0
    end
  end,
  on_cost = function (self, event, target, player, data)
    player.room:handleAddLoseSkills(player, "-#plum__tunquan_levelup")
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player.dead then return end
    room:changeMaxHp(player, 1)
    if not player:isWounded() then return end
    room:recover{ who = player, num = 1, skillName = self.name, recoverBy = player, }
  end,

  refresh_events = {fk.CardUseFinished},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self) and data.card and table.contains(data.card.skillNames, tunquan.name)
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:handleAddLoseSkills(player, "-#plum__tunquan_levelup")
  end,
}
Fk:addSkill(tunquan_levelup)

TT.loadSkill(tunquan, { name = "吞权",
  detail = "结束阶段，你可以弃置任意张牌，然后视为使用一张目标为手牌数不小于你的角色的【万箭齐发】。期间你手牌数由最小变为最大后，你加1点体力上限并回复1点体力。",
})
Fk:loadTranslationTable {
  ["#plum__tunquan_levelup"] = "吞权",
  ["#tunquan_discard"] = "吞权：可以弃置任意张牌，然后视为使用一张目标为手牌数不小于你的角色的【万箭齐发】",
}

yuwanghou:addSkill(tunquan)

return extension
